package com.lin.cloud.disk.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.lin.cloud.disk.common.constant.RedisConstant;
import com.lin.cloud.disk.common.exception.BusinessException;
import com.lin.cloud.disk.entity.dto.UserDTO;
import com.lin.cloud.disk.entity.pojo.User;
import com.lin.cloud.disk.entity.request.*;
import com.lin.cloud.disk.entity.response.UserInfoResponse;
import com.lin.cloud.disk.mapper.UserMapper;
import com.lin.cloud.disk.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * (User)表服务实现类
 *
 * @author ljc
 * @since 2020-12-10 16:48:58
 */
@Service
@Slf4j
public class UserServiceImpl implements IUserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 通过账号密码获取用户信息
     * @param loginRequest
     * @return
     */
    @Override
    public User getUserByUserNameAndPassword(LoginRequest loginRequest) {
        return userMapper.selectUserByUserNameAndPassword(loginRequest);
    }

    /**
     * 更新用户信息
     * @param user
     */
    @Override
    public void update(User user) {
        User updateUser  = new User();
        BeanUtil.copyProperties(user,updateUser,false);
        updateUser.setUpdateTime(new Date());
        if (null != user.getUsername()){
            updateUser.setUpdateBy(user.getUsername());
        }
        userMapper.updateById(updateUser);
    }

    /**
     * 添加用户
     * @param user
     */
    @Override
    public void insert(User user) {
        userMapper.insert(user);
    }

    /**
     * 修改个人信息
     * @param request
     */
    @Override
    public void modifyUserInfo(ModifyUserInfoRequest request){
        User updateUser  = new User();
        BeanUtil.copyProperties(request,updateUser,false);
        updateUser.setUpdateBy(request.getUserDTO().getUsername());
        updateUser.setUpdateTime(new Date());
        updateUser.setId(request.getUserDTO().getId());
        Integer updateCount = userMapper.updateById(updateUser);
        // 更新失败
        if (updateCount == 0){
            throw new BusinessException("更新用户信息失败");
        }
        // 更新成功 更新Redis缓存
        String userJson = stringRedisTemplate.opsForValue().get(RedisConstant.SHIRO_USER + request.getUserDTO().getId());
        if (StringUtils.isNotBlank(userJson)){
            UserDTO userDTO = JSONUtil.toBean(userJson, UserDTO.class);
            // 将数据更新到userDTO对象中
            BeanUtil.copyProperties(request,userDTO);
            // 重新写回缓存
            stringRedisTemplate.opsForValue().set(RedisConstant.SHIRO_USER + request.getUserDTO().getId(),JSONUtil.toJsonStr(userDTO), 30 , TimeUnit.DAYS);
        }
    }


    /**
     * 获取部门用户数据
     * @param userIdList
     */
    @Override
    public List<UserInfoResponse> getDepartmentUserInfoByUserIdList(List<Long> userIdList){
        if (CollectionUtils.isEmpty(userIdList)){
            return Collections.EMPTY_LIST;
        }
        List<UserInfoResponse> userInfoResponseList = userMapper.getDepartmentUserInfoByUserIdList(userIdList);
        if (CollectionUtils.isEmpty(userInfoResponseList)){
            return Collections.EMPTY_LIST;
        }
        return userInfoResponseList;
    }

    /**
     * 获取部门用户数据
     * @param userIdList
     */
    @Override
    public List<UserInfoResponse> getDepartmentUserInfoUserIdList(List<Long> userIdList, Long companyId){
        List<UserInfoResponse> userInfoResponseList = userMapper.getDepartmentUserInfoUserIdList(userIdList , companyId);
        if (CollectionUtils.isEmpty(userInfoResponseList)){
            return Collections.EMPTY_LIST;
        }
        return userInfoResponseList;
    }

    /**
     * 统计用户数量
     * @param request
     * @return
     */
    @Override
    public Integer countUserSize(CountTotalSizeRequest request) {
        return userMapper.countUserSize(request);
    }

    /**
     * 获取用户详情列表
     * @param request
     * @return
     */
    @Override
    public List<UserInfoResponse> getUserInfoList(GetUserInfoListRequest request){
        request.setCompanyId(request.getUserDTO().getCompanyId());
        List<UserInfoResponse> userInfoResponseList = userMapper.getUserInfoList(request);
        if (CollectionUtil.isEmpty(userInfoResponseList)){
            return Collections.EMPTY_LIST;
        }
        return userInfoResponseList;
    }


    /**
     * 通过ID列表删除用户
     * @param request
     */
    @Override
    public void deleteUserByIdList(DeleteUserByIdListRequest request){
        List<Long> idList = request.getIdList();
        if (CollectionUtil.isNotEmpty(idList)){
            Long companyId = request.getUserDTO().getCompanyId();
            userMapper.deleteByIdList(idList,companyId);
            // 删除成功后 删除相关缓存
            List<String> deleteKeyList = new ArrayList<>();
            for (Long userId : idList) {
                deleteKeyList.add(RedisConstant.JWT_ACCESS_TOKEN + userId);
                deleteKeyList.add(RedisConstant.SHIRO_USER + userId);
                deleteKeyList.add(RedisConstant.SHIRO_ROLES + userId);
                deleteKeyList.add(RedisConstant.SHIRO_PERMISSIONS + userId);
                deleteKeyList.add(RedisConstant.USER_PERMISSION_LIST + userId);
            }
            stringRedisTemplate.delete(deleteKeyList);
        }
    }

    /**
     * 检查用户名
     *
     * @param userName
     * @return
     */
    @Override
    public Boolean isContainUserName(String userName) {
        Long userId  = userMapper.getUserIdByUserName(userName);
        return null != userId;
    }

    /**
     * 获取公司内所有的用户ID
     * @param companyId
     * @return
     */
    @Override
    public List<Long> findUserIdListByCompanyId(Long companyId){
        List<Long> userIdLst = userMapper.findUserIdListByCompanyId(companyId);
       return CollectionUtil.isEmpty(userIdLst) ? Collections.EMPTY_LIST: userIdLst;
    }
}